/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.brainstretch.ejb.session;

import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
import javax.ejb.Singleton;
import javax.ejb.LocalBean;
import javax.ejb.Schedule;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceUnit;
import org.brainstretch.recommend.ProfileDimension;

/**
 *
 * @author mrodaitis
 */
@Singleton
@LocalBean
public class NormalizationManager {
    
    @PersistenceUnit(unitName="BrainStretchPU")
    EntityManagerFactory entityManagerFactory;
    
    private QueryBackedDouble numQuizzes;
    private QueryBackedDouble maxDuration;
    private QueryBackedDouble maxAvgScore;
    private QueryBackedDouble maxAvgAPQ;
    private QueryBackedDouble maxAvgQPerSet;
    private QueryBackedDouble maxQLength;
    private QueryBackedDouble maxALength;
    private QueryBackedDouble maxTimePerQ;

    private List<QueryBackedDouble> properties;

    public NormalizationManager() {
        properties = new ArrayList<QueryBackedDouble>();
        
        maxDuration = new QueryBackedDouble("Quiz.maxDuration");
        properties.add(maxDuration);
        
        maxAvgScore = new QueryBackedDouble("QuizProfile.maxAvgScore");
        properties.add(maxAvgScore);
        
        maxAvgAPQ = new QueryBackedDouble("QuizProfile.maxAvgAPQ");
        properties.add(maxAvgAPQ);
        
        maxAvgQPerSet = new QueryBackedDouble("QuizProfile.maxQPerSet");
        properties.add(maxAvgQPerSet);
        
        maxQLength = new QueryBackedDouble("QuizProfile.maxQLength");
        properties.add(maxQLength);
        
        maxALength = new QueryBackedDouble("QuizProfile.maxALength");
        properties.add(maxALength);
        
        maxTimePerQ = new QueryBackedDouble("QuizProfile.maxTPerQ");
        properties.add(maxTimePerQ);
        
        numQuizzes = new QueryBackedDouble("Quiz.count");
    }

    public double getMaxALength() {
        return maxALength.getValue();
    }

    public double getMaxAvgAPQ() {
        return maxAvgAPQ.getValue();
    }

    public double getMaxAvgQPerSet() {
        return maxAvgQPerSet.getValue();
    }

    public double getMaxAvgScore() {
        return maxAvgScore.getValue();
    }

    public double getMaxDuration() {
        return maxDuration.getValue();
    }

    public double getMaxQLength() {
        return maxQLength.getValue();
    }

    public double getMaxTimePerQ() {
        return maxTimePerQ.getValue();
    }

    public double getNumQuizzes() {
        return numQuizzes.getValue();
    }
    
    public EnumMap<ProfileDimension, Double> getNormalizationMap(){
        EnumMap<ProfileDimension, Double> map = new EnumMap<ProfileDimension, Double>(ProfileDimension.class);
        map.put(ProfileDimension.Duration, maxDuration.getValue());
        map.put(ProfileDimension.AnswerLength, maxALength.getValue());
        map.put(ProfileDimension.AttmeptsPerQuestion, maxAvgAPQ.getValue());
        map.put(ProfileDimension.AvgScore, maxAvgScore.getValue());
        map.put(ProfileDimension.QuestionLength, maxQLength.getValue());
        map.put(ProfileDimension.QuestionsPerSet, maxAvgQPerSet.getValue());
        map.put(ProfileDimension.TimePerQuestion, maxTimePerQ.getValue());
        return map;
    }
    
    @Schedule(minute = "*", second = "0", dayOfMonth = "*", month = "*", year = "*", hour = "*", dayOfWeek = "*")
    public void updateNumQuizzes(){        
        EntityManager entityManager = entityManagerFactory.createEntityManager();
        numQuizzes.updateValue(entityManager);
//        System.out.println(numQuizzes.getValue());
        entityManager.close();
    }
    
    @Schedule(minute = "*", second = "0", dayOfMonth = "*", month = "*", year = "*", hour = "*", dayOfWeek = "*")
    public void updateAll() {        
        EntityManager entityManager = entityManagerFactory.createEntityManager();    
        if((int)numQuizzes.getValue() != 0){
            for(QueryBackedDouble prop: properties){
                prop.updateValue(entityManager);;
            }
        }
        entityManager.close();
    }
       
    private class QueryBackedDouble{
        String queryName;
        double value;

        public QueryBackedDouble(String queryName) {
            this.queryName = queryName;
            value = 0;
        }
        
        public void updateValue(EntityManager em){
            Object result = em.createNamedQuery(queryName).getSingleResult();
            if(result instanceof Integer){
                value = (Integer)result;
            }
            else if(result instanceof Long){
                value = ((Long)result).doubleValue();
            }
            else{
                value = (Double)result;
            }
        }

        public double getValue() {
            return value;
        }
    }

    
}
